
#include "ParserBuffer.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>

namespace soft_renderer
{
	ParserBuffer::ParserBuffer(char* buffer, int content_length)
		: BUFFER(buffer), CONTENT_SIZE(content_length), index(0)
	{
	}

	ParserBuffer::~ParserBuffer()
	{
		if (BUFFER != NULL)
		{
			delete BUFFER;
		}
	}

	// 对xt数据进行预处理
	void ParserBuffer::PreProcessSTLData()
	{
	}

	void ParserBuffer::SkipLine()
	{
		char c;
		while (true)
		{
			c = GetChar();
			if (c == '\r')
			{
				c = PeekChar();
				if (c == '\n')
				{
					index++;
				}
				break;
			}
			else if (c == '\n')
			{
				break;
			}
		}
	}

	void ParserBuffer::SkipWord()
	{
		while (true)
		{
			if (GetChar() == ' ')
			{
				break;
			}
		}
	}

	void ParserBuffer::ReadWord(const char* word, bool ignoreLeadingSpace)
	{
		// 跳过前导空格
		char c;
		if (ignoreLeadingSpace)
		{
			while (true)
			{
				c = GetChar();
				if (!isspace(c))
				{
					Back();
					break;
				}
			}
		}
		for (int i = 0; word[i] != '\0'; i++)
		{
			char c = GetChar();
			if (c != word[i])
			{
				throw "format error: unexpected word";
			}
		}
	}

	void ParserBuffer::SkipWS()
	{
		char c;
		while (true)
		{
			c = GetChar();
			if (!isspace(c))
			{
				Back();
				break;
			}
		}
	}

	std::string ParserBuffer::ReadNext(int len)
	{
		if (len <= 0)
		{
			throw "argument error: len should > 0";
		}
		if (len + index > CONTENT_SIZE)
		{
			throw "format error: not enough chars";
		}
		char* buf = new char[len + 1];
		int i;
		for (i = 0; i < len; i++)
		{
			buf[i] = BUFFER[index];
			index++;
		}
		buf[i] = '\0';
		return std::string(buf);
	}

	std::string ParserBuffer::ReadLine()
	{
		CheckEOF();
		const int MAX_SIZE = 80;
		char buf[MAX_SIZE + 1];
		int i;
		for (i = 0; i < MAX_SIZE; i++)
		{
			if (BUFFER[index] == '\n')
			{
				index++;
				break;
			}
			else if (index == MAX_SIZE)
			{
				break;
			}
			buf[i] = BUFFER[index];
			index++;
		}
		buf[i] = '\0';
		return std::string(buf);
	}

	void ParserBuffer::ReadLine(char* buf, const int MAX_SIZE)
	{
		CheckEOF();
		int i;
		for (i = 0; i < MAX_SIZE; i++)
		{
			if (BUFFER[index] == '\n')
			{
				index++;
				break;
			}
			else if (index == MAX_SIZE)
			{
				break;
			}
			buf[i] = BUFFER[index];
			index++;
		}
		buf[i] = '\0';
	}


	void ParserBuffer::Back(int step)
	{
		index--;
	}

	char ParserBuffer::GetChar()
	{
		CheckEOF();
		char c = BUFFER[index];
		index++;
		return c;
	}

	void ParserBuffer::CheckEOF()
	{
		if (index >= CONTENT_SIZE)
		{
			throw "format error: EOF";
		}
	}

	double ParserBuffer::ReadDouble()
	{
		char buf[81];
		int i = 0;
		char c;
		// 跳过空白字符：空格符，制表符，换行符
		while (isspace(c = GetChar())) {}

		do
		{
			if (c == '+' || c == '-' || c == '.' || c == 'e' || (c >= '0' && c <= '9'))
			{
				buf[i] = c;
				i++;
				c = GetChar();
			}
			else
			{
				Back();
				buf[i] = '\0';
				break;
			}
		} while (true);

		return atof(buf);
	}

	char ParserBuffer::PeekChar()
	{
		return BUFFER[index];
	}

	bool ParserBuffer::ReachSTLEnd()
	{
		return PatternCheck("endsolid", 8);
	}

	bool ParserBuffer::PatternCheck(const char* pattern, int len)
	{
		for (int i = 0; i < len; i++)
		{
			if (BUFFER[index + i] != pattern[i])
			{
				return false;
			}
		}
		return true;
	}
}

